package es.udc.emarketapp.http.controller.actions.orders;

import es.udc.emarketapp.emarket.model.client.vo.ClientVO;
import es.udc.emarketapp.emarket.model.order.vo.OrderVO;
import es.udc.emarketapp.emarket.model.orderLine.vo.OrderLineVO;
import es.udc.emarketapp.emarket.model.product.vo.ProductVO;
import es.udc.emarketapp.emarket.model.productFacade.ProductFacade;
import es.udc.emarketapp.emarket.model.purchase.purchaseFacade.PurchaseFacade;
import es.udc.emarketapp.emarket.model.purchase.purchaseFacade.vo.OrderResumeChunkVO;
import es.udc.emarketapp.emarket.model.purchase.vo.PurchaseVO;
import es.udc.emarketapp.emarket.model.seller.vo.SellerVO;
import es.udc.emarketapp.emarket.model.shoppingFacade.vo.OrderCartVO;
import es.udc.emarketapp.emarket.model.shoppingFacade.vo.OrderLineCartVO;
import es.udc.emarketapp.emarket.model.usersFacade.UsersFacade;
import es.udc.emarketapp.http.controller.session.SessionManager;
import es.udc.emarketapp.http.view.actionForms.FindOrdersForm;
import es.udc.fbellas.j2ee.util.exceptions.InstanceNotFoundException;
import es.udc.fbellas.j2ee.util.exceptions.InternalErrorException;
import es.udc.fbellas.j2ee.util.struts.action.DefaultAction;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

public class FindOrdersAction extends DefaultAction {

    public final static String ORDER_ATTRIBUTE = "order";
    public final static String DATE_ATTRIBUTE = "date";
    public final static String CLIENT_ATTRIBUTE = "client";

    public ActionForward doExecute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException, InternalErrorException {

        /* Get data. */
        String idUser = SessionManager.getIdUser(request);

        FindOrdersForm findForm = (FindOrdersForm) form;
        String identifierType = findForm.getIdentifierType();
        Long identifierAsLong = findForm.getIdentifierAsLong();
        String identifier = findForm.getIdentifier();


        if (FindOrdersForm.ORDER_IDENTIFIER.equals(identifierType)) {
            return doFindOrderById(mapping, identifierAsLong,
                    findForm.getStartIndex(), findForm.getCount(), request);
        } else {

            if (FindOrdersForm.SELLER_IDENTIFIER.equals(identifierType)) {
                return doFindOrdersBySeller(mapping, identifier,
                        findForm.getStartIndex(), findForm.getCount(), request);
            } else {
                if (FindOrdersForm.PAID_PENDENT_IDENTIFIER.equals(identifierType)) {
                    return doFindOrdersByPaidPendent(mapping, identifier, findForm.getStartIndex(),
                            findForm.getCount(), request);
                } else {
                    if (FindOrdersForm.PAID_PENDENT_AND_SELLER_IDENTIFIER.equals(identifierType)) {
                        return doFindOrdersByPaidPendentAndSeller(mapping, identifier,
                                findForm.getStartIndex(), findForm.getCount(), request);
                    } else {
                        if (FindOrdersForm.SHIPPING_PENDENT_IDENTIFIER.equals(identifierType)) {
                            return doFindOrdersByShippingPendent(mapping, identifier,
                                    findForm.getStartIndex(), findForm.getCount(), request);
                        } else {
                            /*FindOrdersForm.SHIPPING_PENDENT_AND_SELLER_IDENTIFIER.equals(identifierType))*/
                            return doFindOrdersByShippingPendentAndSeller(mapping, identifier,
                                    findForm.getStartIndex(), findForm.getCount(), request);
                        }
                    }
                }
            }

        }
    }

    private ActionForward doFindOrderById(ActionMapping mapping,
            Long identifier, int startIndex, int count,
            HttpServletRequest request) throws InternalErrorException {


        try {

            PurchaseFacade purchaseFacade = new PurchaseFacade();

            OrderVO order = purchaseFacade.findOrderById(identifier);


            PurchaseVO purchase = purchaseFacade.findPurchaseById(order.getOrderDetails().getnCompra());


            UsersFacade usersFacade = new UsersFacade();
            ProductFacade productFacade = new ProductFacade();
            ClientVO client;
            SellerVO seller;
            ProductVO product;
            String nomProd;
            String nomEmp;
            Double precioProd;

            //recuperamos el nombre del cliente
            client = usersFacade.findClientById(purchase.getIdComprador());

            //recuperamos el nombre de empresa
            seller = usersFacade.findSellerById(order.getOrderDetails().getIdVendedor());
            nomEmp = seller.getNomEmp();


            //creamos los LineOrderCarts a partir de los LineOrders
            List<OrderLineCartVO> orderLinesCart =
                    new ArrayList<OrderLineCartVO>();

            for (OrderLineVO orderLine : order.getOrderLines()) {

                //recuperamos el nombre de producto y precio
                product = productFacade.findProductById(
                        orderLine.getIdProd());
                nomProd = product.getNomProd();
                precioProd = product.getPrecio();


                orderLinesCart.add(new OrderLineCartVO(
                        orderLine.getnLinea(), orderLine.getnPedido(),
                        orderLine.getnCompra(), orderLine.getIdProd(),
                        nomProd, orderLine.getUds(), precioProd,
                        orderLine.getValor(), orderLine.getPeso()));

            }

            OrderCartVO orderCart = new OrderCartVO(nomEmp,
                    order.getOrderDetails(), orderLinesCart);


            request.setAttribute(ORDER_ATTRIBUTE, orderCart);
            request.setAttribute(DATE_ATTRIBUTE, purchase.getFecha());
            request.setAttribute(CLIENT_ATTRIBUTE, client);

            return mapping.findForward("FindOrderByIdSuccess");

        } catch (InstanceNotFoundException e) {

            ActionMessages errors = new ActionMessages();

            errors.add("identifier",
                    new ActionMessage("ErrorMessages.order.notFound"));
            saveErrors(
                    request, errors);


            return new ActionForward(mapping.getInput());

        }
    }

    private ActionForward doFindOrdersBySeller(ActionMapping mapping,
            String identifier, int startIndex, int count,
            HttpServletRequest request) throws InternalErrorException {


        PurchaseFacade purchaseFacade = new PurchaseFacade();
        OrderResumeChunkVO orderResumeChunkVO = purchaseFacade.findOrdersResumeBySeller(identifier, startIndex, count);

        if (orderResumeChunkVO.getOrderResumeVOs().size() > 0) {
            request.setAttribute("orders", orderResumeChunkVO.getOrderResumeVOs());


        } /* Generate parameters for previous and next links. */
        Map previousLinkParameters = getPreviousLinkParameters(identifier,
                FindOrdersForm.SELLER_IDENTIFIER, startIndex, count);

        if (previousLinkParameters != null) {
            request.setAttribute("previous", previousLinkParameters);
        }

        if (orderResumeChunkVO.getExistMoreOrders()) {
            Map nextLinkParameters = getNextLinkParameters(identifier,
                    FindOrdersForm.SELLER_IDENTIFIER, startIndex, count);
            request.setAttribute("next", nextLinkParameters);

        } /* Return ActionForward. */
        return mapping.findForward("FindOrdersBySellerSuccess");

    }

    private ActionForward doFindOrdersByPaidPendent(ActionMapping mapping,
            String identifier, int startIndex, int count,
            HttpServletRequest request) throws InternalErrorException {


        PurchaseFacade purchaseFacade = new PurchaseFacade();
        OrderResumeChunkVO orderResumeChunkVO =
                purchaseFacade.findOrdersResumeByPaidPendent(startIndex, count);

        if (orderResumeChunkVO.getOrderResumeVOs().size() > 0) {
            request.setAttribute("orders", orderResumeChunkVO.getOrderResumeVOs());


        } /* Generate parameters for previous and next links. */
        Map previousLinkParameters = getPreviousLinkParameters(identifier,
                FindOrdersForm.PAID_PENDENT_IDENTIFIER, startIndex, count);

        if (previousLinkParameters != null) {
            request.setAttribute("previous", previousLinkParameters);
        }

        if (orderResumeChunkVO.getExistMoreOrders()) {
            Map nextLinkParameters = getNextLinkParameters(identifier,
                    FindOrdersForm.PAID_PENDENT_IDENTIFIER, startIndex, count);
            request.setAttribute("next", nextLinkParameters);

        } /* Return ActionForward. */
        return mapping.findForward("FindOrdersBySellerSuccess");

    }

    private ActionForward doFindOrdersByPaidPendentAndSeller(ActionMapping mapping,
            String identifier, int startIndex, int count,
            HttpServletRequest request) throws InternalErrorException {

        PurchaseFacade purchaseFacade = new PurchaseFacade();
        OrderResumeChunkVO orderResumeChunkVO =
                purchaseFacade.findOrdersResumeByPaidPendentAndSeller(identifier, startIndex, count);


        if (orderResumeChunkVO.getOrderResumeVOs().size() > 0) {
            request.setAttribute("orders", orderResumeChunkVO.getOrderResumeVOs());


        } /* Generate parameters for previous and next links. */
        Map previousLinkParameters = getPreviousLinkParameters(identifier,
                FindOrdersForm.PAID_PENDENT_AND_SELLER_IDENTIFIER, startIndex, count);

        if (previousLinkParameters != null) {
            request.setAttribute("previous", previousLinkParameters);
        }

        if (orderResumeChunkVO.getExistMoreOrders()) {
            Map nextLinkParameters = getNextLinkParameters(identifier,
                    FindOrdersForm.PAID_PENDENT_AND_SELLER_IDENTIFIER, startIndex, count);
            request.setAttribute("next", nextLinkParameters);

        } /* Return ActionForward. */
        return mapping.findForward("FindOrdersBySellerSuccess");

    }

    private ActionForward doFindOrdersByShippingPendent(ActionMapping mapping,
            String identifier, int startIndex, int count,
            HttpServletRequest request) throws InternalErrorException {


        PurchaseFacade purchaseFacade = new PurchaseFacade();
        OrderResumeChunkVO orderResumeChunkVO =
                purchaseFacade.findOrdersResumeByShippingPendent(startIndex, count);

        if (orderResumeChunkVO.getOrderResumeVOs().size() > 0) {
            request.setAttribute("orders", orderResumeChunkVO.getOrderResumeVOs());


        } /* Generate parameters for previous and next links. */
        Map previousLinkParameters = getPreviousLinkParameters(identifier,
                FindOrdersForm.SHIPPING_PENDENT_IDENTIFIER, startIndex, count);

        if (previousLinkParameters != null) {
            request.setAttribute("previous", previousLinkParameters);
        }

        if (orderResumeChunkVO.getExistMoreOrders()) {
            Map nextLinkParameters = getNextLinkParameters(identifier,
                    FindOrdersForm.SHIPPING_PENDENT_IDENTIFIER, startIndex, count);
            request.setAttribute("next", nextLinkParameters);

        } /* Return ActionForward. */
        return mapping.findForward("FindOrdersBySellerSuccess");

    }

    private ActionForward doFindOrdersByShippingPendentAndSeller(ActionMapping mapping,
            String identifier, int startIndex, int count,
            HttpServletRequest request) throws InternalErrorException {

        PurchaseFacade purchaseFacade = new PurchaseFacade();
        OrderResumeChunkVO orderResumeChunkVO =
                purchaseFacade.findOrdersResumeByShippingPendentAndSeller(identifier, startIndex, count);


        if (orderResumeChunkVO.getOrderResumeVOs().size() > 0) {
            request.setAttribute("orders", orderResumeChunkVO.getOrderResumeVOs());


        } /* Generate parameters for previous and next links. */
        Map previousLinkParameters = getPreviousLinkParameters(identifier,
                FindOrdersForm.SHIPPING_PENDENT_AND_SELLER_IDENTIFIER, startIndex, count);

        if (previousLinkParameters != null) {
            request.setAttribute("previous", previousLinkParameters);
        }

        if (orderResumeChunkVO.getExistMoreOrders()) {
            Map nextLinkParameters = getNextLinkParameters(identifier,
                    FindOrdersForm.SHIPPING_PENDENT_AND_SELLER_IDENTIFIER, startIndex, count);
            request.setAttribute("next", nextLinkParameters);

        } /* Return ActionForward. */
        return mapping.findForward("FindOrdersBySellerSuccess");

    }

    private Map getPreviousLinkParameters(String identifier, String identifierType,
            int startIndex, int count) {

        Map linkAttributes = null;

        if ((startIndex - count) > 0) {

            linkAttributes = getCommonPreviousNextLinkParameters(identifier,
                    identifierType, startIndex, count);
            linkAttributes.put("startIndex", new Integer(startIndex - count));
        }

        return linkAttributes;

    }

    private Map getNextLinkParameters(String identifier, String identifierType,
            int startIndex, int count) {

        Map linkAttributes = getCommonPreviousNextLinkParameters(identifier,
                identifierType, startIndex, count);
        linkAttributes.put("startIndex", new Integer(startIndex + count));

        return linkAttributes;

    }

    private Map getCommonPreviousNextLinkParameters(String identifier,
            String identifierType, int startIndex, int count) {

        Map linkAttributes = new HashMap();

        linkAttributes.put("identifier", identifier);
        linkAttributes.put("identifierType", identifierType);
      //  linkAttributes.put("startIndex", new Integer(startIndex));
        linkAttributes.put("count", new Integer(count));

        return linkAttributes;

    }
}
